<?php
	$this->assign('title', "Emulaci&oacute;n de Recorrido - miBus");
	
	$recorridos_url = $this->Html->url(array("controller" => "Predicciones", "action" => "obtener_recorridos_realizados_ruta", "ext" => "json"));
	$ruta_coords_ajax = $this->Html->url(array("controller" => "Predicciones", "action" => "obtener_coordenadas_ruta", "ext" => "json"));
	$paradas_url = $this->Html->url(array("controller" => "Predicciones", "action" => "obtener_paradas_ruta", "ext" => "json"));		
	$coordenadas_gps_url = $this->Html->url(array("controller" => "Predicciones", "action" => "obtener_coordenadas_simple_recorrido", "ext" => "json"));
	$recuperar_estado_url = $this->Html->url(array("controller" => "Predicciones", "action" => "recuperar_estado_recorrido_realizado", "ext" => "json"));	
	$establecer_estado_url = $this->Html->url(array("controller" => "Predicciones", "action" => "establecer_estado_recorrido_realizado", "ext" => "json"));		
	
	$base_url = $this->Html->url('/');
?>
<script type="text/javascript" charset="UTF-8" src="http://js.cit.api.here.com/se/2.5.4/jsl.js?with=all"></script>
<script type="text/javascript" charset="UTF-8" src="<?php echo $base_url; ?>js/prediccion_mapas.js"></script>
<script type="text/javascript" charset="UTF-8" src="<?php echo $base_url; ?>js/prediccion_ruta.js"></script>
<!--
<form action="/Predicciones/establecer_estado_recorrido_realizado" method="POST" target="_blank">
	<input type="hidden" name="id_recorrido_realizado" value="407">
	<input type="hidden" name="estado_recorrido_realizado" value="movimiento">
	<input type="hidden" name="latitud" value="6.15602000000000100">
	<input type="hidden" name="longitud" value="-75.51738333333333000">
	<input type="hidden" name="velocidad_promedio" value="0.0">
	<input type="hidden" name="id_proxima_parada" value="85">
	<input type="hidden" name="fecha_actualizacion_recorrido" value="2014-06-16 16:53:06">
	<input type="hidden" name="fecha_salida" value="2014-06-16 16:33:08">
	<input type="submit" value="Enviar">
</form>
-->
<table align="center">
	<tr>
		<td>Ruta:</td>
		<td>
			<select id="id_ruta_id" name="ruta_id" onchange="ruta_seleccionada(this.value);">										
				<option value="0" selected>[Seleccione Ruta]</option>
				<?php				
					foreach ($todas_rutas as $key => $values){
						echo "<option value=\"".$values["id_ruta"]."\">(".$values["id_ruta"].") - ".$values["nombre_ruta"]."</option>";
					}
				?>
			</select>
		</td>
		<td colspan="1"><br /></td>
	</tr>	
	<tr>
		<td>Recorrido:</td>
		<td>
			<select id="id_recorrido_realizado" name="recorrido_id">										
				<option value="0" selected>[Seleccione Recorrido]</option>
			</select>
		</td>
		<td>
			<input type="button" id="id_emular_recorrido" name="emular_recorrido" value="Emular Recorrido" 
					onclick="iniciar_recorrido_ruta();" style="font-size: 8pt;">
			<input type="button" id="id_detener_recorrido" name="detener_recorrido" value="Detener Recorrido"
					onclick="detener_recorrido();" style="font-size: 8pt; display: none;">
		</td>
	</tr>
</table>
<table align="center">
	<tr>
		<td>
			<div id="mapContainer" style="height: 400px; width: 1050px;"></div>
		</td>
	</tr>
</table>
<table align="center">
	<tr>
		<td><input type="text" id="id_app_message_1" name="app_message" value="Messages..." style="font-size: 8pt;"></td>
		<td style="text-align: center;">									
			<textarea id="id_app_message_2" name="name="app_message_2" " cols="40" rows="3" style="font-size: 8pt;"></textarea>
		</td>
	</tr>
</table>
<script type="text/javascript" id="map_source">	
	var ultimo_ruta_id;
	var	ultimo_recorrido_id;
	
	//Ruta...
	var current_waypoints_ayuda = [];
	var current_paradas = [];
	var coordenadas_ruta = [];
	var coordenadas_gps = [];
	var paradas_posiciones;
	
	//Emulacion...
	var tiempo_inicio_emulacion;
	var intervalo_emulacion = null;
	var parada_actual;
	var coordenada_actual;
	var last_server_coord;
	var estado_inicial_recorrido;
	
	//Inicializar mapas...
	iniciar_mapas();
	
	var markersContainer = {
		buses: new nokia.maps.map.Container(), 
		rutas: new nokia.maps.map.Container(), 
		paradas: new nokia.maps.map.Container(),		
	};
	
	var icon_parada = new nokia.maps.gfx.BitmapImage("<?php echo $base_url; ?>img/parada_3.png", null, 30, 30, 0, 0);	
	var icon_desdeeia = new nokia.maps.gfx.BitmapImage("<?php echo $base_url; ?>img/bus_desde_eia.png", null, 33, 22, 0, 0);
	var busMarker = new nokia.maps.map.Marker(
		new nokia.maps.geo.Coordinate(Number(6.2359), Number(-75.5751)),{
		icon: icon_desdeeia,
		anchor: new nokia.maps.util.Point(16, 11)
	});
	var busCircleMarker = new nokia.maps.map.Circle(
		new nokia.maps.geo.Coordinate(Number(6.2359), Number(-75.5751)), 100, 
		{brush: {color:"#6EC4FFAA"}, pen: {strokeColor: "#089AFF"}}
	);
	
	function establecer_habilitado(habilitado){
		document.getElementById('id_ruta_id').disabled = !habilitado;
		document.getElementById('id_recorrido_realizado').disabled = !habilitado;
		document.getElementById('id_emular_recorrido').disabled = !habilitado;		
	}
	
	function limpiar_combobox(combobox){
		var length = combobox.options.length;
		for (i = 0; i < length; i++) {
			combobox.options[i] = null;
		}
		
		combobox.options.length = 0;
	}

	function nueva_opcion(valor, texto){
		var extra_opcion = document.createElement('option');
		extra_opcion.text = texto;
		extra_opcion.value = valor;
		
		return extra_opcion;
	}
	
	function ruta_seleccionada(ruta_id){	
		//Actualiza el contenido del combobox
		$.get("<?php echo $recorridos_url; ?>?id_ruta=" + ruta_id, 
			function(data_recorridos){
				var combo_recorridos = document.getElementById('id_recorrido_realizado');
				limpiar_combobox(combo_recorridos);
				
				combo_recorridos.add(nueva_opcion(0,"[Seleccione Recorrido]"));
				
				for (var i = 0; i < data_recorridos.length; i++){
					combo_recorridos.add(
						nueva_opcion(data_recorridos[i].id_recorrido_realizado, 
									"(" + data_recorridos[i].id_recorrido_realizado + ") - " + data_recorridos[i].fecha_salida)
					);
				}				
			});	
	}
	
	function iniciar_recorrido_ruta(){
		var ruta_id = document.getElementById('id_ruta_id').value;
		var recorrido_id = document.getElementById('id_recorrido_realizado').value;
		
		if (ruta_id == 0){
			alert("Debe seleccionar ruta");
			return;
		}
		
		if (recorrido_id == 0){
			alert("Debe seleccionar recorrido");
			return;
		}
		
		if (!confirm('Advertencia: Esto habilitara nuevamente el recorrido seleccionado y recreara el recorrido ' +
					'en tiempo real. No se recomienda su uso en horarios donde recorridos reales estan siendo llevados ' +
					'a cabo. Una vez iniciada la emulacion, debera esperar a que la misma termine o creara inconsistencias ' +
					'en la base de datos. Realmente desea continuar?')){
			return;
		}
		
		establecer_habilitado(false);
		document.getElementById('id_detener_recorrido').style.display = '';
		
		ultimo_recorrido_id = recorrido_id;
		
		if (ultimo_ruta_id != ruta_id){
			//Actualizar todo...
			ultimo_ruta_id = ruta_id;		
			
			//Recuperar coordenadas de ruta guardadas en server
			$.get("<?php echo $ruta_coords_ajax; ?>?id_ruta=" + ultimo_ruta_id, 
				function(data_recuperada){
					coordenadas_ruta = data_recuperada;											
					
					//Solicitar data de ruta para dibujarla...
					$.get("<?php echo $paradas_url; ?>?id_ruta=" + ultimo_ruta_id, coordenadas_recuperadas);			
				}
			);			
		} else {
			//Reiniciar nuevo recorrido en misma ruta...
			seguir_recorrido_ruta();
		}						
	}
	
	//Funcion que grafica la ruta una vez que se ha calculado....
	var onRouteCalculated = function (observedRouter, key, value) {
		
		if (value == "finished") {
			var routes = observedRouter.getRoutes(),
				route = routes[0],
				waypoints = route.waypoints,
				i, length = waypoints.length;
			
			var lineColor = "#285999";
			
			var linea_ruta = new nokia.maps.map.Polyline(route.shape, {
				pen : new nokia.maps.util.Pen({
					lineWidth: 5, 
					strokeColor: lineColor
				}),
				arrows: new nokia.maps.util.Arrows({
					color: "#FFFFFF"
				})
			});
			
			linea_ruta.set("id_ruta", observedRouter.get("id_ruta"));
			linea_ruta.addListener("mouseover" ,  function(evt) { 
				evt.target.set("pen", new nokia.maps.util.Pen({
					lineWidth: 5, 
					strokeColor: "#F54046"
				}));
				evt.target.set("zIndex", 100);
				map.update(-1, 0);
			});
			linea_ruta.addListener("mouseout" ,  function(evt) {
				evt.target.set("pen", new nokia.maps.util.Pen({
					lineWidth: 5, 
					strokeColor: lineColor
				}));
				evt.target.set("zIndex", 2);
				map.update(-1, 0);
			});
			
			//Agregar la ruta al mapa, quitando la anterior
			map.objects.remove(markersContainer.rutas);
			markersContainer.rutas.objects.clear();
			markersContainer.rutas.objects.add(linea_ruta);
			map.objects.add(markersContainer.rutas);
			
			//Dibujar las paradas
			var waypoints_ayuda_positions = observedRouter.get("waypoints_ayuda_positions");
			var paradas_waypoints = observedRouter.get("paradas_waypoints");
			map.objects.remove(markersContainer.paradas);
			markersContainer.paradas.objects.clear();
			for (i = 0; i < length; i++) {
				if (waypoints_ayuda_positions.indexOf(i) != -1) {
					continue;
				}

				var markerParada = new nokia.maps.map.Marker(waypoints[i].originalPosition, {
					icon: icon_parada,
					anchor: new nokia.maps.util.Point(15, 15)
				});
				markerParada.parada = paradas_waypoints[i];
				
				markersContainer.paradas.objects.add(markerParada);
			}
			map.objects.add(markersContainer.paradas);
			
			//Obtener posiciones de cada parada....
			paradas_posiciones = puntos_cercanos_coordenadas(current_paradas, coordenadas_ruta);
			
			//Iniciar simulacion....
			seguir_recorrido_ruta();
		} else if (value == "failed") {
			alert("Fallo en enrutamiento!");
			
			ultimo_ruta_id = null;
			ultimo_recorrido_id = null;
		}	
	};	
	
	function seguir_recorrido_ruta(){
		//Descargar estado actual del recorrido..
		$.get("<?php echo $recuperar_estado_url; ?>?id_recorrido_realizado=" + ultimo_recorrido_id, 
			function(data_recorrido){
				estado_inicial_recorrido = data_recorrido[0];
				
				//Descargar todas las coordenadas GPS...
				$.get("<?php echo $coordenadas_gps_url; ?>?id_recorrido_realizado=" + ultimo_recorrido_id, 
					function(data_gps){
						coordenadas_gps = data_gps;
						
						if (coordenadas_gps.length == 0){
							alert("No hay coordenadas registradas para el recorrido seleccionado");
							establecer_habilitado(true);
							return;
						}
						
						if (intervalo_emulacion != null){
							clearInterval(intervalo_emulacion);				
						}
						
						tiempo_inicio_emulacion = new Date();	
						last_server_coord = null;
						parada_actual = 0;
						coordenada_actual = 0;
						
						intervalo_emulacion = setInterval(continuar_emulacion, 1000.0);	
					});							
			});						
	}
	
	function continuar_emulacion(){
		var tiempo_actual = new Date();
		var delta_segundos = (tiempo_actual.getTime() - tiempo_inicio_emulacion.getTime()) / 1000.0;
		//delta_segundos *= 5.0; //Temporal
		
		//Actualizar coordenada actual...
		var tiempo_inicial = dateStringToSeconds(coordenadas_gps[0].fecha_hora_envio_servidor);
		
		//Actualizar DB si coordenada actual cambia
		var i, tiempo_coordenada, delta_coordenada;
		for (i = coordenada_actual; i < coordenadas_gps.length; i++){
			//Analizar tiempo entre coordenadas...
			tiempo_coordenada = dateStringToSeconds(coordenadas_gps[i].fecha_hora_envio_servidor);
			delta_coordenada = tiempo_coordenada - tiempo_inicial;
			
			if (delta_coordenada > delta_segundos){
				//No interesan coordenadas mas recientes que la actual...
				break;
			} else {
				//Moverse a siguiente coordenada ....
				new_server_coord = coordenadas_gps[i];
				coordenada_actual = i;
			}
		}
		
		if (last_server_coord != new_server_coord){
			//Actualiza la visualizacion del bus...
			actualizarPosicionBus(new_server_coord.latitud, new_server_coord.longitud)
			
			//Determinar proxima parada...			
			var punto_cercano = punto_cercano_ruta_abs(new_server_coord.latitud, new_server_coord.longitud, coordenadas_ruta);
			
			while (parada_actual < current_paradas.length - 1 &&
			   paradas_posiciones[parada_actual + 1].index + paradas_posiciones[parada_actual + 1].tfact <  
			   punto_cercano.index + punto_cercano.tfact){
				parada_actual++;				
			}
						
			//Actualizar server....
			$.post("<?php echo $establecer_estado_url; ?>", 
				{
					id_recorrido_realizado: ultimo_recorrido_id, 
					estado_recorrido_realizado: 'movimiento',
					latitud: new_server_coord.latitud, 
					longitud: new_server_coord.longitud,
					velocidad_promedio: 0.0,
					id_proxima_parada: current_paradas[parada_actual + 1].id_parada,
				}
			).done(function(data){
				if (data.resultado == "1"){
					last_server_coord = new_server_coord;
				} else {
					alert("Hubo un error al establecer estado: " + data.mensaje);
				}								
			});
		}
		
		if (coordenada_actual == coordenadas_gps.length - 1 &&
			delta_coordenada < delta_segundos + 10){
			//Ultima coordenada y ha pasado cierto tiempo, finalizar emulacion...
			detener_recorrido();
		}
		
		document.getElementById('id_app_message_1').value = "T = " + delta_segundos;
		document.getElementById('id_app_message_2').value = "coordenada_actual = " + coordenada_actual + ", Siguiente actualizacion = " + delta_coordenada + 
															", P=" + punto_cercano.index + ", P_FACT = " + punto_cercano.tfact + 
															", Siguiente parada: " + current_paradas[parada_actual + 1].nombre_parada;
		
	}
	
	function detener_recorrido(){
		$.post("<?php echo $establecer_estado_url; ?>", 
				{
					id_recorrido_realizado: ultimo_recorrido_id, 
					estado_recorrido_realizado: 'finalizado',
					latitud: estado_inicial_recorrido.latitud, 
					longitud: estado_inicial_recorrido.longitud,
					velocidad_promedio: estado_inicial_recorrido.velocidad_promedio,
					id_proxima_parada: estado_inicial_recorrido.id_proxima_parada,
					fecha_actualizacion_recorrido: estado_inicial_recorrido.fecha_actualizacion_recorrido,
					fecha_salida: estado_inicial_recorrido.fecha_salida,
				}
			).done(function(data){
				if (data.resultado == "0"){
					alert("Hubo un error al finalizar recorrido: " + data.mensaje);
				}
			});
			
		document.getElementById('id_detener_recorrido').style.display = 'none';
			
		//Detener emulacion...
		clearInterval(intervalo_emulacion);
		intervalo_emulacion = null;
		
		alert("Emulacion finalizada");
	}
	
	function reiniciarVisualizacionBus(){
		//Remover cualquier instancia previa...
		map.objects.remove(markersContainer.buses);
		markersContainer.buses.objects.clear();
		
		//Agregar nueva instancia...
		markersContainer.buses.objects.add(busMarker);	
		markersContainer.buses.objects.add(busCircleMarker);
		map.objects.add(markersContainer.buses);
	}

	function actualizarPosicionBus(latitud, longitud){		
		//Actualizar coordenada de marcador
		busMarker.coordinate = new nokia.maps.geo.Coordinate(Number(latitud), Number(longitud));	
		
		busCircleMarker = new nokia.maps.map.Circle(
			new nokia.maps.geo.Coordinate(Number(latitud), Number(longitud)), 100, 
			{brush: {color:"#6EC4FFAA"}, pen: {strokeColor: "#089AFF"}}
		);
				
		reiniciarVisualizacionBus();	
			
	}
</script>